B1=100.0
ROE=0.2
PB=5.0
f=0.5

def E(n:float):
    assert(n>=0)
    if n == 0:
        return 0
    elif n == 1:
        return (2 * B1 * ROE)/(2 - ROE)
    else:
        return E(1) * pow((2+ROE-2*f*ROE)/(2-ROE), n-1)
    
def priceBeforeDividends(n:float):
    '''
    第n年年初#!未分红股价
    '''
    assert(n>=1)
    if n == 1:
        return PB*B1
    return PB*(B1*(2 + ROE)/(2 - ROE)*pow((2 + ROE - 2*f*ROE)/(2 - ROE), n-2))

def priceAfterdDividends(n:float):
    '''
    第n年年初#!分红后股价
    '''
    assert(n>=1)
    if n == 1:
        return PB*B1
    return PB*(B1*(2 + ROE)/(2 - ROE)*pow((2 + ROE - 2*f*ROE)/(2 - ROE), n-2) - f*E(n-1))
    #我认为f*E(n-1)要乘以PB，即放在括号里计算，
    #否则如果假设一家公司股本=1，资产￥100，PB=2，股价为￥200。极端一点，假设此时1派￥100，
    #则分红后净资产为0，1派￥100后股价为￥0，而不是200-100=100。

def H(n:float, hold_init:float = 1):
    '''
    第n年年初红利再投资购入后总股本
    '''
    assert(n>=1)
    if n == 1:
        return hold_init
    else:
        return (f*E(n-1)/priceAfterdDividends(n) + 1)*H(n-1)
        #假设一家公司年末，每股净资产￥50，PB=2，此时股价￥100
        #此时我有1股，1派￥25(即假设25=f*E(n-1))，则此时每股净资产剩下￥25，
        #此时股价为PB*25=￥50，我手头有1股以及￥25
        #可以用当前的￥25买下0.5股，共1.5股。第二年每股收益假设￥10，则每股净资产￥35，
        #公司决定1派￥5，则派发后每股净资产￥30，股价PB*30=￥60，
        # 我手头有现金1.5股*￥5=￥7.5


if __name__ == '__main__':
    第10年年初红利再投资后总股本 = H(10)
    第11年年初_即第十年年末未分红股价 = priceBeforeDividends(11)
    第十年年末资产 = 第10年年初红利再投资后总股本*第11年年初_即第十年年末未分红股价
    十年复利年化收益率 = 100*(pow(第十年年末资产/(PB*B1), 0.1)-1)
    print(第10年年初红利再投资后总股本, 第11年年初_即第十年年末未分红股价, 第十年年末资产, '%.2f%%' % (十年复利年化收益率))

    